﻿using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.IdentityModel.Tokens;

namespace suirui.ZhuMu.WebCore
{
    public class CustomAuthorziationFilter : Attribute, Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {
            //throw new NotImplementedException();
        }
    }

    //public class CustomAuthorziationFilter : AuthorizationFilterAttribute
    //{
    //    public override void OnAuthorization(HttpActionContext actionContext)
    //    {
    //        //如果用户方位的Action带有AllowAnonymousAttribute，则不进行授权验证
    //        if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any())
    //        {
    //            return;
    //        }
    //        var verifyResult = actionContext.Request.Headers.Authorization != null &&  //要求请求中需要带有Authorization头
    //                           actionContext.Request.Headers.Authorization.Parameter.Contains("Bearer"); //并且Authorization参数为123456则验证通过

    //        if (!verifyResult)
    //        {
    //            //如果验证不通过，则返回401错误，并且Body中写入错误原因
    //            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, new HttpError("Token 不正确"));
    //        }
    //    }
    //}

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class TokenFilterAttribute : AuthorizationFilterAttribute
    {
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            var attr = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
            bool isAnonymous = attr.Any(a => a is AllowAnonymousAttribute);
            if (!isAnonymous)
            {
                var authorization = actionContext.Request.Headers.Authorization;
                var result = ValidateToken(authorization.Scheme);
                if (!result)
                {
                    actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
                }
            }
        }

        public static bool ValidateToken(string token)
        {
            var principal = GetPrincipal(token);
            var identity = principal?.Identity as ClaimsIdentity;
            if (identity == null)
            {
                return false;
            }
            if (!identity.IsAuthenticated)
            {
                return false;
            }
            var nameClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
            var username = nameClaim?.Value;
            if (string.IsNullOrEmpty(username))
            {
                return false;
            }

            return true;
        }

        private static ClaimsPrincipal GetPrincipal(string token)
        {
            try
            {
                string Secret = string.Empty;
                var tokenHandler = new JwtSecurityTokenHandler();
                var jwtToken = tokenHandler.ReadToken(token) as JwtSecurityToken;
                if (jwtToken == null)
                {
                    return null;
                }
                var symmetricKey = Convert.FromBase64String(Secret);
                var validationParams = new TokenValidationParameters()
                {
                    RequireExpirationTime = true,
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    IssuerSigningKey = new SymmetricSecurityKey(symmetricKey),
                };
                SecurityToken securityToken;
                var pincipal = tokenHandler.ValidateToken(token, validationParams, out securityToken);
                return pincipal;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

    //public class UserController : ApiController
    //{
    //    public string Login([FromBody]LoginReq req)
    //    {
    //        var token = TokenManager.GenerateToken(req.username);
    //    }
    //}
}

